//
//  GgData.m
//  AppFinance
//
//  Created by wei on 12-6-10.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "AFMarketData.h"

#import "AFSetting.h"
//#import "AFMarketNetData.h"

#include <Math.h>

static AFMarketData *_ggData = nil;

@implementation AFMarketData


+(AFMarketData*) data{
    @synchronized(self){
        if (_ggData == nil) {
            _ggData = [[self alloc] init];            
        }
    }
    return _ggData;
}

// ---------------------------- [S] 分时数据 -------------------------------------
-(void) lastClose:(NSString*)_close{
    lastClose = _close;
}

-(void) timeRemoveDrawListArray{
    if (self.drawTimeListArray != nil) {
        [self.drawTimeListArray removeAllObjects];
    }
    if (self.drawTimeAverageListArray != nil) {
        [self.drawTimeAverageListArray removeAllObjects];
    }
    if (self.drawTimeVolumeListArray != nil) {
        [self.drawTimeVolumeListArray removeAllObjects];
    }
}

-(void)initServerTimeListArray:(NSArray *)_array{
    if (self.serverTimeListArray == nil) {
        self.serverTimeListArray = [NSMutableArray array];
    } else {
        [self.serverTimeListArray removeAllObjects];
    }
    
    //NSLog(@" serverTimeListArray _array = %@",_array);
    
    [self.serverTimeListArray addObjectsFromArray:_array];
    
    [self setTimeHigh:0];
    [self setTimeLow:100000000];

    // 计算分时数据绘制坐标
    [self serverTimeDataToLocalTimeData];
}

// 计算分时数据绘图坐标
-(void) serverTimeDataToLocalTimeData{
    if (self.serverTimeListArray == nil) {
        return;
    }
    // 分时线坐标
    if (self.drawTimeListArray == nil) {
        self.drawTimeListArray = [NSMutableArray array];
    }else {
        [self.drawTimeListArray removeAllObjects];
    }
    
    // 分时图均线
    if (self.drawTimeAverageListArray == nil) {
        self.drawTimeAverageListArray = [NSMutableArray array];
    } else {
        [self.drawTimeAverageListArray removeAllObjects];
    }
    
    //分时图范围: 左上角坐标(0,0) -- 右下角(220,172)
    // 分时 k
    float point = [[AFMarketData data] draw]; // 国际黄金需要绘制的坐标数: 24*60/5 = 288
    
    // 分钟点长度
    float min_w = [AFSetting QUARTZ_TIME_W]/point;

    float low = 100000000.0;  // 最底点
    float high = 0.0; // 最高点
    float l;
    float h = 0;
    int volume = 0; // 交易量
    
    NSDictionary *itemDict = nil;
    float max_volume = 0;
        
    //计算最大、最小点的值，获取每个点的值
    for (int i = 0; i < [self.serverTimeListArray count]; i++) {
        itemDict = [self.serverTimeListArray objectAtIndex:i];
        l = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_LOW]] floatValue];
        h = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_HIGH]] floatValue];
        volume = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_VOLUME]] intValue];
        
        if(low > l){
            low = l;
            //NSLog(@" i = %i  l = %f",i,l);
        }
        
        if(high < h){
            high = h;
        }

        // 最大交易量
        if(volume > max_volume){
            max_volume = volume;
        }
    }
    
    // [S] 分时图 以昨收为中间价格
    if(lastClose != nil){
        float middle = [lastClose floatValue];
        
        float h_m = fabs(high - middle);
        float m_l = fabs(middle - low);
        
        if (h_m >= m_l) {
            high = middle + h_m;
            low = middle - h_m;
        }else {
            high = middle + m_l;
            low = middle - m_l;
        }
    }
    // [E]
    
    // 保存最高点和最低点
    if (self.timeHigh < high) {
        [self setTimeHigh:high];
    }
    if (self.timeLow > low) {
        [self setTimeLow:low];
    }
    
    if(!self.serverTimeListArray ||[self.serverTimeListArray count]== 0){
        [self setTimeHigh:0];
        [self setTimeLow:0];
    }

    //NSLog(@"low = %f  high = %f",self.timeLow, self.timeHigh);

    // 计算坐标
    float min_y = 0.0;
    float min_h = self.timeHigh - self.timeLow;
    if((high - low) == 0){
        min_y = 0; //停牌、数据不变、取不到数据等情况，这时候就在最高点画一条线
    } else {
        min_y = [AFSetting QUARTZ_TIME_H]/min_h; // 实际高度／间隔高度 ＝ y轴分段高度
    }
    //NSDecimalNumber *multiplierNumber = [NSDecimalNumber decimalNumberWithString:multiplierValue];
    //NSLog(@"min_w = %f  min_y = %f  min_h = %f",min_w,min_y,min_h);

    NSMutableDictionary *localItem = nil;
    float x = 0;
    float y = 0;
    if(min_y == 0){ 
        for (int k = 0; k < [self.serverTimeListArray count]; k++) {
            localItem = [NSMutableDictionary dictionary];
            if(k == 0){
                x = 0;
            } else {
                x = 0 + k*min_w;
            }

            localItem = [NSMutableDictionary dictionary];
            [localItem setObject:@"0" forKey:@"average"];
            [localItem setObject:[NSString stringWithFormat:@"%f",x] forKey:@"x"];
            [localItem setObject:[NSString stringWithFormat:@"%f",[AFSetting QUARTZ_TIME_H]/2] forKey:@"y"];
            [self.drawTimeListArray addObject:localItem];
            
            //[self.drawTimeAverageListArray addObject:localItem];
        }
    } else {
        float close = 0;
        float close_h = 0;
        
        int volume = 0;
        double totalValue = 0;
        double totalTrade = 0;
        double timeAverage = 0;
        float timeAverage_h = 0;
        float timeAverage_y  = 0;
        
        for(int k = 0; k < [self.serverTimeListArray count]; k++){
            itemDict = [self.serverTimeListArray objectAtIndex:k];
            
            close = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_CLOSE]] floatValue];
            close_h = close - self.timeLow;   // close 点 相对高度 ＝ close点高度 － 最低点的高度
            y = [AFSetting QUARTZ_TIME_H] - min_y*close_h;    // y 最大坐标 － 换算后的高度 ＝ y轴新的坐标
 
            if(k == 0){
                x = 0;
            } else {
                x = 0 + k*min_w;
            }

            localItem = [NSMutableDictionary dictionary];
            [localItem setObject:[NSString stringWithFormat:@"%f",x] forKey:@"x"];
            [localItem setObject:[NSString stringWithFormat:@"%f",y] forKey:@"y"];
            [self.drawTimeListArray addObject:localItem];
            
            
            // 计算分时均价
            //某一时点的均价＝开盘时到这个时点的所有的 成交价格×相应的成交股数/开盘时到这个时点总成交量
            //把所有时点的均价连成线就是股票分时图的均线
            volume = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_VOLUME]] intValue];
            if (volume != 0) {
                totalValue = totalValue + close * volume;
                totalTrade = totalTrade + volume;
                
                timeAverage = totalValue / totalTrade;
                
                timeAverage_h = timeAverage - self.timeLow;   // close 点 相对高度 ＝ close点高度 － 最低点的高度
                timeAverage_y = [AFSetting QUARTZ_TIME_H] - min_y*timeAverage_h;    // y 最大坐标 － 换算后的高度 ＝ y轴新的坐标
                
                localItem = [NSMutableDictionary dictionary];
                [localItem setObject:[NSString stringWithFormat:@"%f",timeAverage] forKey:AF_K_MARKET_AVERAGE];
                [localItem setObject:[NSString stringWithFormat:@"%f",x] forKey:@"x"];
                [localItem setObject:[NSString stringWithFormat:@"%f",timeAverage_y] forKey:@"y"];
                [self.drawTimeAverageListArray addObject:localItem];
            }
        }
    }
    
    // 交易量 坐标 计算
    // 分时 底部 交易量
    //交易量:  左上角坐标(0,174) -- 右下角(220,254)
    if (self.drawTimeVolumeListArray == nil) {
        self.drawTimeVolumeListArray = [NSMutableArray array];
    }else {
        [self.drawTimeVolumeListArray removeAllObjects];
    }
    
    self.timeMaxVolume = max_volume;
    
    //float f_w = 660;  // 数据量 y 终坐标
    //float f_h = 120;   // 数据量 高度
    //float f_ey = 120;  // 最低点坐标

    // 上海黄金分时
    //if (gglistType == 1) {
    //    f_w = 220;
    //}

    NSMutableDictionary *localVolumeItem = nil;
    if(max_volume > 0){
        int volume = 0;
        
        float volume_h = [AFSetting QUARTZ_VOLUME_H]/max_volume; // 实际高度／间隔高度 ＝ y轴分段高度
        float volume_x = 0;
        float volume_y = 0;
        
        float close1 = 0.0;
        float close2 = 0.0;
        NSString *stauts = @"up"; //up/down
        for (int k = 0; k < [self.serverTimeListArray count]; k++) {
            
            itemDict = [self.serverTimeListArray objectAtIndex:k];
            
            close2 = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_CLOSE]] floatValue];
            if(k == 0){
                close1 = close2;
            }
            
            // 判断走势
            if(close2 > close1){
                stauts = @"up";
            } else {
                stauts = @"down";
            }
            //NSLog(@" close1 = %f, close2 = %f, stauts = %@",close1, close2, stauts);

            close1 = close2;
            
            volume = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_VOLUME]] intValue];
            volume_y = [AFSetting QUARTZ_VOLUME_H] - volume*volume_h; // y 最大坐标 － 换算后的高度 ＝ y轴新的坐标
            
            if(k == 0){
                volume_x = 0;
            } else {
                volume_x = 0 + k*min_w;
            }
            
            localVolumeItem = [NSMutableDictionary dictionary];
            [localVolumeItem setValue:[NSString stringWithFormat:@"%f",volume_x] forKey:@"x1"];
            [localVolumeItem setValue:[NSString stringWithFormat:@"%f",[AFSetting QUARTZ_VOLUME_H]] forKey:@"y1"];
            [localVolumeItem setValue:[NSString stringWithFormat:@"%f",volume_x] forKey:@"x2"];
            [localVolumeItem setValue:[NSString stringWithFormat:@"%f",volume_y] forKey:@"y2"];
            [localVolumeItem setValue:stauts forKey:@"status"]; // up/down
            
            [self.drawTimeVolumeListArray addObject:localVolumeItem];
        }
    }
}

#pragma mark - 获取手指移动对应的 数据
-(NSDictionary*) timeCurrentPointInfo:(float)_x{
    
    NSDictionary *info;
    
    NSString *close = @"0";
    NSString *average = @"0";
    NSString *volume = @"0";
    NSString *date = @"0";
    
    if (self.serverTimeListArray == nil) {
        info = @{@"close": close, @"average": average, @"volume": volume, @"date": date};
        return info;
    }
    
    float maxPoint = [[AFMarketData data] draw]; // 国际黄金需要绘制的坐标数: 24*60/5 = 288
    float _p = [AFSetting QUARTZ_TIME_W]/maxPoint;
    
    int _index = floor(_x/_p);
    
    int _count = (int)[self.serverTimeListArray count];
    
    
    //NSLog(@" self.serverTimeListArray = %@", self.serverTimeListArray);
    //NSLog(@" 11 timeCurrentPointInfo _count = %i, _index = %i", _count, _index);
    
    NSDictionary *itemDict;
    if ((_count - 1) >= _index) {
        itemDict = [self.serverTimeListArray objectAtIndex:_index];
        
        NSLog(@" itemDict = %@", itemDict);
        
        close = [itemDict objectForKey:@"close"];
        
        volume = [itemDict objectForKey:@"volume"];
        
        date = [itemDict objectForKey:@"date"];
    }

    _count = (int)[self.drawTimeAverageListArray count];
    
    //NSLog(@" 22 timeCurrentPointInfo _count = %i, _index = %i", _count, _index);
    if ((_count - 1) >= _index) {
        itemDict = [self.drawTimeAverageListArray objectAtIndex:_index];
        average = [itemDict objectForKey:@"average"];
        

    }
    
    //NSLog(@" close = %@", close);
    //NSLog(@" volume = %@", volume);
    //NSLog(@" date = %@", date);
    //NSLog(@" average = %@", average);
    
    info = @{@"close": close, @"average": average, @"volume": volume, @"date": date};
    //NSLog(@" info = %@", info);
    
    return info;
}
// ---------------------------- [E] 分时数据 -------------------------------------








#pragma mark - ========== kline数据 ========== 
// --------------------------- [S] kline数据 ------------------------------------
-(float)lastKLineMinH{
    return last_KLineMinH;
}

-(float)lastKLineHigh{
    return last_KLineHigh;
}

-(float)lastKLineLow{
    return last_KLineLow;
}


-(void)drawMAStartIndex:(int)_startIndex withDrawCount:(int)_drawCount{
    startIndex = _startIndex;
    DrawCount = _drawCount;
}
// 烛台图 原始数据 转换 为 坐标点数据
-(NSMutableArray*)serverKLineDataToLocalKLineDataWithArray:(NSArray*)kLineArray {
    
    NSMutableArray *drawKLineZTListArray = [NSMutableArray array];
    
    // 如果没有数据则返回
    if (kLineArray == nil || [kLineArray count] <= 0) {
        return drawKLineZTListArray;
    }
  
    // [S] 计算最底点 和 最 高点
    float min_low = 0;  // 最底点
    float max_high = 0; // 最高点
    float l;
    float h = 0;
    NSDictionary *itemDict = nil;
    
    int start_index = 22;
    
    if ([kLineArray count] < 22) {
        start_index = 0;
    }

    NSLog(@"[kLineArray count] = %i",(int)[kLineArray count]);
    
    for (int i = 0; i < [kLineArray count]; i++) {
        itemDict = [kLineArray objectAtIndex:i];
        l = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_LOW]] floatValue];
        h = [[NSString stringWithFormat:@"%@",[itemDict objectForKey:AF_K_MARKET_HIGH]] floatValue];

        if(i == 0){
            min_low = l;
            max_high = h;
        } else {
            if(min_low > l){
                min_low = l;
            }
            
            if(max_high < h){
                max_high = h;
            }
        }
    }
    
    if (max_high==min_low) {
        return nil;
    }
    
    
    for (int k = startIndex ;k < startIndex + DrawCount; k ++) {
        float ma5 = [self.drawMA5ListArray[k] floatValue];
        float ma10 = [self.drawMA10ListArray[k] floatValue];
        float ma20 = [self.drawMA20ListArray[k] floatValue];
        if(ma5 >  max_high){
            max_high = ma5;
        }
        if(ma10 >  max_high){
            max_high = ma10;
        }
        if(ma20 >  max_high){
            max_high = ma20;
        }
    }
    
    last_KLineHigh = max_high;
    last_KLineLow = min_low;
    // [E]

    // 烛台范围: 左上角坐标(0,0) -- 右下角(320,160)
    // k线  
    float s_zt_sx = 0; //50
    float s_zt_ey = [AFSetting QUARTZ_KLINE_H];
    float s_zt_w = [AFSetting QUARTZ_KLINE_W];
    float s_zt_h = [AFSetting QUARTZ_KLINE_H];

    // 计算 x 轴上 每段 长度
    float min_w = s_zt_w/[AFSetting AF_DRAW_COUNT];
    // 计算 y 轴上 每段 长度
    float max_h_count = max_high - min_low;       // 计算y轴间隔数
    float min_h = s_zt_h/max_h_count;             // 计算最小间隔长度
    
    // 最后一次 最小高度 记录
    last_KLineMinH = min_h;

    // [S] 绘图坐标计算
    NSMutableDictionary *localItem;
    
    // 烛台图矩形坐标绘制计算方法，取得最高点的坐标，根据最高点和最底点计算出要绘制的长度，宽度是固定的
    float open;
    float close;
    float high,low;
    float x = 0;    // 烛台起点x坐标
    float y = 0;    // 烛台起点y坐标
    float y_h = 0;  // 烛台高度
    NSString *stauts = nil;
    
    int t_count = (int)[kLineArray count];
    for (int i = 0; i < t_count; i++) {
        itemDict = [kLineArray objectAtIndex:i];
        
        open = [[itemDict objectForKey:AF_K_MARKET_OPEN] floatValue];
        close = [[itemDict objectForKey:AF_K_MARKET_CLOSE] floatValue];
        high = [[itemDict objectForKey:AF_K_MARKET_HIGH] floatValue];
        low = [[itemDict objectForKey:AF_K_MARKET_LOW] floatValue];

        // [S]走高 走底 判断
        if (close >= open) {
            stauts = @"up"; //up/down
        } else {
            stauts = @"down"; //up/down
        }
        // [E]
        
        // x = 烛台x轴开始坐标 ＋ 条数*x轴最小宽度
        x = s_zt_sx + i*min_w;
        
        // y = 烛台y轴最大坐标 －（高点－最底高度）* y轴分段高度
        // y_h ＝ （高点－底点）* y轴分段高度
        if(open >= close){
            y = s_zt_ey - (open - min_low)*min_h;
            y_h = (open - close)*min_h;
        } else {
            y = s_zt_ey - (close - min_low)*min_h;
            y_h = (close - open)*min_h;
        }

        localItem = [NSMutableDictionary dictionary];
        [localItem setValue:stauts forKey:@"status"]; // up/down
        [localItem setValue:[NSString stringWithFormat:@"%f",x+1] forKey:@"x"];
        [localItem setValue:[NSString stringWithFormat:@"%f",y] forKey:@"y"];
        [localItem setValue:[NSString stringWithFormat:@"%f",min_w - 2] forKey:@"x_w"];
        [localItem setValue:[NSString stringWithFormat:@"%f",y_h] forKey:@"y_h"];
        
        //float open,close,high,low;
        // 计算是否需要绘制 最高点
        if (high > open && high > close) {
            [localItem setValue:@"yes" forKey:@"has_hight"];
            // 如果有，计算 烛台图举行上线到最高点的坐标
            float h_x1 = x + min_w/2;
            float h_y1 = y;
            float h_x2 = x + min_w/2;
            float h_y2 = s_zt_ey - (high - min_low)*min_h;
            [localItem setValue:[NSString stringWithFormat:@"%f",h_x1] forKey:@"h_x1"];
            [localItem setValue:[NSString stringWithFormat:@"%f",h_y1] forKey:@"h_y1"];
            [localItem setValue:[NSString stringWithFormat:@"%f",h_x2] forKey:@"h_x2"];
            [localItem setValue:[NSString stringWithFormat:@"%f",h_y2] forKey:@"h_y2"];
        } else {
            [localItem setValue:@"no" forKey:@"has_hight"];
        }
        // 计算是否需要绘制 最低点
        if (low < open && low < close) {
            [localItem setValue:@"yes" forKey:@"has_low"];
            // 如果有，计算 烛台图举行下线到最高点的坐标
            float l_x1 = x + min_w/2;
            float l_y1 = y + y_h;
            float l_x2 = x + min_w/2;
            float l_y2 = s_zt_ey - (low - min_low)*min_h;
            [localItem setValue:[NSString stringWithFormat:@"%f",l_x1] forKey:@"l_x1"];
            [localItem setValue:[NSString stringWithFormat:@"%f",l_y1] forKey:@"l_y1"];
            [localItem setValue:[NSString stringWithFormat:@"%f",l_x2] forKey:@"l_x2"];
            [localItem setValue:[NSString stringWithFormat:@"%f",l_y2] forKey:@"l_y2"];
        } else {
            [localItem setValue:@"no" forKey:@"has_low"];
        }
        
        // [S] 每条线对应的数据保存
        [localItem setValue:[itemDict objectForKey:AF_K_MARKET_OPEN] forKey:AF_K_MARKET_OPEN];
        [localItem setValue:[itemDict objectForKey:AF_K_MARKET_CLOSE] forKey:AF_K_MARKET_CLOSE];
        [localItem setValue:[itemDict objectForKey:AF_K_MARKET_HIGH] forKey:AF_K_MARKET_HIGH];
        [localItem setValue:[itemDict objectForKey:AF_K_MARKET_LOW] forKey:AF_K_MARKET_LOW];
        [localItem setValue:[itemDict objectForKey:AF_K_MARKET_UPDATETIME] forKey:AF_K_MARKET_UPDATETIME];
        
        // [E]
        [drawKLineZTListArray addObject:localItem];
    }
    // [E] 绘图坐标计算
    
    return drawKLineZTListArray;
}

// 计算 k 线 MA 数据
- (void) serverKLineDataToMALocal:(NSArray*)kLineArray{

    // MA array初始化
    if (self.drawMA5ListArray == nil) {
        self.drawMA5ListArray = [NSMutableArray array];
    } else {
        [self.drawMA5ListArray removeAllObjects];
    }
    if (self.drawMA10ListArray == nil) {
        self.drawMA10ListArray = [NSMutableArray array];
    } else {
        [self.drawMA10ListArray removeAllObjects];
    }
    if (self.drawMA20ListArray == nil) {
        self.drawMA20ListArray = [NSMutableArray array];
    } else {
        [self.drawMA20ListArray removeAllObjects];
    }
    
    // 如果没有数据则返回
    if (kLineArray == nil) {
        return;
    }

    NSDictionary *itemDict;

    // MA data
    int all_close_count = (int)[kLineArray count];
    //NSLog(@" ma all_close_count = %i", all_close_count);
    
    float close = 0;
    float ma5 = 0;
    float ma10 = 0;
    float ma20 = 0;

    float tempClose = 0;
    
    float ma5_prev = 0;
    float ma10_prev = 0;
    float ma20_prev = 0;

    float ma5_close = 0;
    float ma10_close = 0;
    float ma20_close = 0;
    
    for(int k = 0; k < all_close_count; k++){
        itemDict = [kLineArray objectAtIndex:k];
        
        close = [[itemDict objectForKey:AF_K_MARKET_CLOSE] floatValue];
        
        ma5_close += close;
        ma10_close += close;
        ma20_close += close;
        
        if (k < 5) {
            ma5 = ma5_close / 5;
        } else {
            itemDict = [kLineArray objectAtIndex:(k-5)];
            tempClose = [[itemDict objectForKey:AF_K_MARKET_CLOSE] floatValue];
            
            ma5_prev += tempClose;
            
            ma5 = (ma5_close - ma5_prev) / 5;
        }

        if (k < 10) {
            ma10 = ma10_close / 10;
        } else {
            itemDict = [kLineArray objectAtIndex:(k-10)];
            tempClose = [[itemDict objectForKey:AF_K_MARKET_CLOSE] floatValue];
            
            ma10_prev += tempClose;
            
            ma10 = (ma10_close - ma10_prev) / 10;
        }
        
        if (k < 20) {
            ma20 = ma20_close / 20;
        } else {
            itemDict = [kLineArray objectAtIndex:(k-20)];
            tempClose = [[itemDict objectForKey:AF_K_MARKET_CLOSE] floatValue];
            
            ma20_prev += tempClose;
            
            ma20 = (ma20_close - ma20_prev) / 20;
        }
        
        //NSLog(@" k = %i, ma5 = %f, ma10 = %f, ma20 = %f", k, ma5, ma10, ma20);
        
        // add data to array
        [self.drawMA5ListArray addObject:[NSNumber numberWithFloat:ma5]];
        [self.drawMA10ListArray addObject:[NSNumber numberWithFloat:ma10]];
        [self.drawMA20ListArray addObject:[NSNumber numberWithFloat:ma20]];
    }
}
// --------------------------- [E] kline数据 ------------------------------------
@end
